#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include "my_serialize.h"
#define SIZE_BUF 256
void test_serialize_char(){
    {
        char data = '@';
        char buffer[256] = {0};
        int offset = 0;
        

        char expect_buffer[256] = {0};
        expect_buffer[offset] = data;
        int expect_ret = 1;
        int ret = serialize_char(buffer,offset,data);
        if(ret == expect_ret && memcmp(buffer,expect_buffer,sizeof(buffer)) == 0){
            printf("1 serialize_char no err\n");
        }
        else{
            printf("1 serialize_char err");
        }
    }
    {
        char data = 'd';
        char buffer[256] = {0};
        int offset = 0;

        int expect_ret = -1;
        char expect_buffer[256] = {0};
        int ret = serialize_char(NULL,offset,data);
        if(ret == expect_ret && memcmp(buffer,expect_buffer,sizeof(buffer)) == 0){
            printf("2 serialize_char no err\n");
        }
        else{
            printf("2 serialize_char has err");
        }
    }
}

void test_unserialize_char(){
    {
        int offset = 5;
        char data = 'Y';
        char buffer[256] = {0};
        buffer[offset] = data;

        char expect_data = data;
        int expect_ret = offset+sizeof(char);
        int ret = unserialize_char(&data,buffer,offset);
        if(ret == expect_ret && data == expect_data){
            printf("1 unserialize_char no err\n");
        }
        else{
            printf("1 unserialize_char has err\n");
        }
    }
    {
        int offset = 8;
        char data = 'w';
        
        char expect_data = data;
        int expect_ret = -1;
        int ret = unserialize_char(&data,NULL,offset);
        if(ret == expect_ret && data == expect_data){
            printf("2 unserialize_char no err\n");
        }
        else{
            printf("2 unserialize_char has err\n");
        }
    }
}

void test_serialize_short(){
    {
        char buffer[SIZE_BUF] = {0};
        short data = 23;
        int offset = 9;

        char expect_buffer[SIZE_BUF] = {0};
        short tmp = htons(data);
        memcpy(expect_buffer+offset,&tmp,sizeof(short));
        int expect_ret = offset+sizeof(short);
        int ret = serialize_short(buffer,offset,data);
        if(expect_ret == ret && memcmp(buffer,expect_buffer,SIZE_BUF) == 0){
            printf("1 serialize_short no err\n");
        }
        else {
            printf("1 serialize_short has err\n");
        }
    }
    {
        char* buffer = NULL;
        short data = -32;
        int offset = 2342;

        char* expect_buffer = NULL;
        int expect_ret = -1;
        int ret = serialize_short(buffer,offset,data);
        if(expect_ret == ret && buffer == expect_buffer){
            printf("2 serialize_short no err\n");
        }
        else {
            printf("2 serialize_short has err\n");
        }
    }
}

void test_unserialize_short(){
    
    {
        short data = 765;
        char buffer[SIZE_BUF] = {0};
        int offset = 87;
        serialize_short(buffer,offset,data);

        int expect_data = data;
        int expect_ret = offset+sizeof(short);
        int ret = unserialize_short(&data,buffer,offset);
        if(expect_ret == ret && expect_data == data){
            printf("1 unserialize_short no err\n");
        }
        else {
            printf("1 unserialize_short has err\n");
        }
    }
    {
        short data = 765;
        char buffer[SIZE_BUF] = {0};
        int offset = -43;

        int expect_data = data;
        int expect_ret = -1;
        int ret = unserialize_short(&data,buffer,offset);
        if(expect_ret == ret && expect_data == data){
            printf("2 unserialize_short no err\n");
        }
        else {
            printf("2 unserialize_short has err\n");
        }
    }
    {
        short data = 765;
        char buffer[SIZE_BUF] = {0};
        int offset = 43;

        int expect_data = data;
        int expect_ret = -1;
        int ret = unserialize_short(&data,NULL,offset);
        if(expect_ret == ret && expect_data == data){
            printf("3 unserialize_short no err\n");
        }
        else {
            printf("3 unserialize_short has err\n");
        }
    }
}

void test_serialize_int(){
    {
        int data = -34;
        char buffer[SIZE_BUF] = {0};
        int offset = 23;

        char expect_buffer[SIZE_BUF] = {0};
        uint32_t tmp = htonl(data);
        memcpy(expect_buffer,&tmp,sizeof(uint32_t));
        int expect_ret = offset + sizeof(uint32_t);
        int ret = serialize_int(buffer,offset,data);
        if(expect_ret == ret && memcpy(buffer,expect_buffer,SIZE_BUF)){
            printf("1 serialize_int no err\n");
        }
        else {
            printf("1 serialize_int has err\n");
        }
    }
    {
        int data = -34;
        char buffer[SIZE_BUF] = {0};
        int offset = -23;

        char expect_buffer[SIZE_BUF] = {0};
        int expect_ret = -1;
        int ret = serialize_int(buffer,offset,data);
        if(expect_ret == ret && memcpy(buffer,expect_buffer,SIZE_BUF)){
            printf("2 serialize_int no err\n");
        }
        else {
            printf("2 serialize_int has err\n");
        }
    }

}

void test_unserialize_int(){
    {
        int data = 0x12345678;
        char buffer[SIZE_BUF] = {0};
        int offset = 6;
        serialize_int(buffer,offset,data);
        int expect_ret = offset+sizeof(uint32_t);
        int expect_data = data;
        int ret = unserialize_int(&data,buffer,offset);
        if(expect_ret == ret && expect_data == data){
            printf("1 unserialize_int no err\n");
        }
        else {
            printf("1 unserialize_int has err\n");
        }
    }
    {
        int data = 0x12345678;
        char buffer[SIZE_BUF] = {0};
        int offset = 6;
        
        int expect_ret = -1;
        int expect_data = 0x12345678;
        int ret = unserialize_int(&data,NULL,offset);
        if(expect_ret == ret && expect_data == data){
            printf("2 unserialize_int no err\n");
        }
        else {
            printf("2 unserialize_int has err\n");
        }
    }
    
}

void test_htonll(){
    {
        uint64_t data = 0x1234567898765432;
        uint64_t expect_ret = 0x3254769878563412;
        
        uint64_t ret = htonll(data);
        if(ret != expect_ret){
            printf("1 htonll has err\n");
        }
        else {
            printf("1 htonll no err\n");
        }
    }
}

void test_ntohll(){
    {
        uint64_t data = 0x0123456789ABCDEF;
        uint64_t expect_ret = 0xEFCDAB8967452301;

        uint64_t ret = ntohll(data);
        if(ret != expect_ret){
            printf("1 ntohll has err\n");
        }
        else {
            printf("1 ntohll no err\n");
        }
    }
}

void test_serialize_uint64_t(){
    {
        long data = 0x123456789ABCD;
        char buffer[SIZE_BUF] = {0};
        int offset = 0;

        char expect_buffer[SIZE_BUF] = {0};
        long tmp = htonll(data);
        memcpy(expect_buffer+offset,&tmp,sizeof(long));
        int expect_ret = offset+sizeof(long);
        int ret = serialize_uint64_t(buffer,offset,data);
        if(expect_ret != ret || memcmp(expect_buffer,buffer,SIZE_BUF) != 0){
            printf("1 serialize_long has err\n");
        }
        else{
            printf("1 serialize_long no err\n");
        }
    }
}

void test_unserialize_uint64_t(){
    {
        char buffer[SIZE_BUF] = {0};
        long data = 0xAAAABBBBCCCC;
        int offset = 3;
        serialize_uint64_t(buffer,offset,data);

        long expect_data = 0xAAAABBBBCCCC;
        int expect_ret = offset+sizeof(long);
        int ret = unserialize_uint64_t(&data,buffer,offset);
        if(expect_ret != ret || expect_data != data){
            printf("1 unserialize_long has err\n");
        }
        else {
            printf("1 unserialize_long no err\n");
        }
    }
}

void test_serialize_string(){
    {
        char data[32] = "12345678";
        int offset = 0;
        char buffer[SIZE_BUF] = {0};
        
        char expect_buffer[SIZE_BUF] = {0};
        int tmp = strlen(data)+1;
        int n = htonl(tmp);
        memcpy(expect_buffer+offset,&n,sizeof(n));
        memcpy(expect_buffer+offset+sizeof(u_int32_t),data,tmp);
        int expect_ret = offset+sizeof(u_int32_t)+tmp;
        int ret = serialize_string(buffer,offset,data);
        if(expect_ret != ret || memcmp(expect_buffer,buffer,SIZE_BUF) != 0){
            printf("1 serialize_string has err\n");
        }
        else {
            printf("1 serialize_string no err\n");
        }
    }
    {
        char data[32] = "";
        int offset = 0;
        char buffer[SIZE_BUF] = {0};
        char expect_buffer[SIZE_BUF] = {0};
        int expect_ret = -1;
        int ret = serialize_string(NULL,offset,data);
        if(expect_ret != ret || memcmp(expect_buffer,buffer,SIZE_BUF) != 0){
            printf("2 serialize_string has err\n");
        }
        else {
            printf("2 serialize_string no err\n");
        }
    }
}

void test_unserialize_string(){
    {
        char data[32] = "adadad";
        int offset = 10;
        char buffer[SIZE_BUF] = {0};
        char expect_data[32] = "adadad";
        int expect_ret = 21;
        serialize_string(buffer,offset,data);
        memset(data,0,sizeof(data));
        int ret = unserialize_string(data,buffer,offset);
        if(expect_ret != ret || memcmp(expect_data,data,sizeof(data))!=0){
            printf("1 unserialize_string has err\n");
        }
        else {
            printf("1 unserialize_string no err\n");
        }
    }
    {
        char *data = NULL;
        int offset = 10;
        char buffer[SIZE_BUF] = {0};
        char *expect_data = NULL;
        int expect_ret = -1;

        int ret = unserialize_string(data,buffer,offset);
        if(expect_ret != ret || expect_data != data){
            printf("2 unserialize_string has err\n");
        }
        else {
            printf("2 unserialize_string no err\n");
        }
    }
    {
        char data[32] = "tiouyytiouyu";
        int offset = 1;
        char buffer[SIZE_BUF] = {0};
        char expect_data[32] = "tiouyytiouyu";
        int expect_ret = -1;

        int ret = unserialize_string(data,NULL,offset);
        if(expect_ret != ret || memcmp(expect_data,data,sizeof(data))){
            printf("3 unserialize_string has err\n");
        }
        else {
            printf("3 unserialize_string no err\n");
        }
    }
}

void test_serialize_arr_ch(){
    {
        char data[5] = {56,34,65,76,13};
        int n = 5;
        int offset = 236;
        char buffer[SIZE_BUF] = {0};

        char expect_buffer[SIZE_BUF] = {0};

        int tmp = htonl(n);
        memcpy(expect_buffer+offset,&tmp,sizeof(tmp));
        memcpy(expect_buffer+offset+sizeof(uint32_t),data,n);
        int expect_ret = offset + sizeof(uint32_t) + n;
        int ret = serialize_arr_ch(buffer,offset,data,n);
        if(expect_ret != ret || memcmp(expect_buffer,buffer,SIZE_BUF) != 0){
            printf("1 serialize_arr_ch has err\n");
        }
        else {
            printf("1 serialize_arr_ch no err\n");
        }
    }
    {
        char data[5] = {56,34,65,76,13};
        int n = 5;
        int offset = 236;
        char* buffer = NULL;

        char* expect_buffer = NULL;

        int expect_ret = -1;
        int ret = serialize_arr_ch(NULL,offset,data,n);
        if(expect_ret != ret || buffer != expect_buffer){
            printf("2 serialize_arr_ch has err\n");
        }
        else {
            printf("2 serialize_arr_ch no err\n");
        }
    }
}

void test_unserialize_arr_ch(){
    {
        char data[5] = {56,34,65,76,13};
        int n = sizeof(data)/sizeof(data[0]);
        int offset = 236;
        char buffer[SIZE_BUF] = {0};

        char expect_data[5] = {56,34,65,76,13};
        int expect_len = 5;
        int expect_ret = n + sizeof(int) + offset;
        serialize_arr_ch(buffer,offset,data,n);
        int ret = unserialize_arr_ch(data,&n,buffer,offset);
        if(expect_ret != ret || expect_len != n || memcmp(expect_data,data,n)){
            printf("1 unserialize_arr_ch has err\n");
        }
        else {
            printf("1 unserialize_arr_ch no err\n");
        }
    }
    {
        char data[5] = {56,34,65,76,13};
        int n = sizeof(data)/sizeof(data[0]);
        int offset = 236;
        char buffer[SIZE_BUF] = {0};

        int expect_len = 5;
        int expect_ret = -1;

        int ret = unserialize_arr_ch(NULL,&n,buffer,offset);
        if(expect_ret != ret || expect_len != n){
            printf("2 unserialize_arr_ch has err\n");
        }
        else {
            printf("2 unserialize_arr_ch no err\n");
        }
    }
}

int main(int argc, char const *argv[])
{
    test_serialize_char();
    test_unserialize_char();
    test_serialize_short();
    test_unserialize_short();
    test_serialize_uint64_t();
    test_unserialize_uint64_t();
    test_htonll();
    test_ntohll();
    test_serialize_int();
    test_unserialize_int();
    test_serialize_string();
    test_unserialize_string();
    test_serialize_arr_ch();
    test_unserialize_arr_ch();
    return 0;
}
